package com.mz.ieann.dokit.utils

import android.util.Base64
import com.alibaba.fastjson.JSONObject
import com.alibaba.fastjson.serializer.SerializerFeature
import java.nio.charset.StandardCharsets
import java.security.MessageDigest
import javax.crypto.Mac
import javax.crypto.SecretKey
import javax.crypto.spec.SecretKeySpec

/**
 * <p>------------------------------------------------------
 * <p> Copyright (C) 2021 zhangmz, All rights reserved.
 * <p> If there is technical discussion, you can contact zhangmz90@foxmail.com
 * <p>------------------------------------------------------
 * <p> 字符加密
 * <p>
 *
 * @author Created by zhangmz
 * @date on 2022/11/28
 */
object EncryptUtil {

    const val HMAC_SHA1 = "HmacSHA1"
    const val HMAC_MD5 = "HmacMD5"
    const val HMAC_SHA256 = "HmacSHA256"
    const val HMAC_SHA512 = "HmacSHA512"

    /**
     * 指定类型加密
     * @param message 需要加密的输入参数
     * @param key 密钥
     * @param algorithm 选择加密算法
     * @return 加密后的值
     */
    fun encrypt(message: String, key: String, algorithm: String): String = runCatching {
        val data = key.toByteArray(StandardCharsets.UTF_8)
        // 根据给定的字节数组构造一个密钥，第二个参数指定一个密钥的算法名称，生成HmacSHA1专属密钥
        val secretKey: SecretKey = SecretKeySpec(data, algorithm)
        // 生成一个指定Mac算法的Mac对象
        val mac = Mac.getInstance(algorithm)
        // 用给定密钥初始化Mac对象
        mac.init(secretKey)
        val text = message.toByteArray(StandardCharsets.UTF_8)
        val encryptByte = mac.doFinal(text)
        val result = Base64.encodeToString(encryptByte, Base64.NO_WRAP)
        result
    }.getOrDefault(message)

    /**
     * md5加密
     */
    fun toMd5(message: String) = runCatching {
        //获取一种摘要算法
        val builder = StringBuilder()
        val instance = MessageDigest.getInstance("MD5")
        val digest = instance.digest(message.toByteArray(StandardCharsets.UTF_8))
        for (b in digest) {
            if (Integer.toHexString(0xFF and b.toInt()).length == 1) {
                builder.append("0").append(Integer.toHexString(0xFF and b.toInt()))
            } else {
                builder.append(Integer.toHexString(0xFF and b.toInt()))
            }
        }
        builder.toString()
    }.getOrDefault(message)

    /**
     * base64加密，可逆
     * Base64.NO_WRAP 不换行不加空格
     */
    fun toBase64(message: String) = runCatching {
        Base64.encodeToString(message.toByteArray(), Base64.NO_WRAP)
    }.getOrDefault(message)

    /**
     * sha-256加密
     * @param message JSON格式
     */
    fun toSHA256(message: String) = runCatching {
//        val json = JSONObject.parseObject(message)
//        val sortJsonStr = JSONObject.toJSONString(json, SerializerFeature.MapSortField)
//        val messageDigest = MessageDigest.getInstance("SHA-256")
//        messageDigest.update(sortJsonStr.toByteArray(Charsets.UTF_8))
//        byte2Hex(messageDigest.digest())
    }

    /**
     * 同 encodeHex
     */
    private fun byte2Hex(bytes: ByteArray): String {
        val stringBuffer = StringBuffer()
        var strTemp: String? = null
        for (i in bytes.indices) {
            strTemp = Integer.toHexString(bytes[i].toInt() and 0xFF)
            if (strTemp.length == 1) {
                stringBuffer.append("0")
            }
            stringBuffer.append(strTemp)
        }
        return stringBuffer.toString()
    }

}